package cn.edu.jxust.core.domain.repository.impl;

import cn.edu.jxust.common.domain.entity.Account;
import cn.edu.jxust.common.domain.entity.Device;
import cn.edu.jxust.common.domain.entity.Site;
import cn.edu.jxust.common.domain.dto.DeviceSiteVo;
import cn.edu.jxust.common.domain.valobj.DeviceVo;
import cn.edu.jxust.common.domain.dto.RegDeviceVo;
import cn.edu.jxust.core.infrastructure.mapper.AccountMapper;
import cn.edu.jxust.core.infrastructure.mapper.AreaMapper;
import cn.edu.jxust.core.infrastructure.mapper.DeviceMapper;
import cn.edu.jxust.core.infrastructure.mapper.EnterpriseMapper;
import cn.edu.jxust.core.infrastructure.mapper.SiteMapper;
import cn.edu.jxust.common.response.Result;
import cn.edu.jxust.common.response.ResultUtils;
import cn.edu.jxust.common.response.enums.ResultStatus;
import cn.edu.jxust.core.domain.repository.DeviceService;
import cn.edu.jxust.core.infrastructure.util.Const;
import cn.edu.jxust.core.infrastructure.util.LocationUtils;
import cn.edu.jxust.core.infrastructure.util.location.Location;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author QiuKangming
 * @since 2020-06-29
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {

    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private AccountMapper accountMapper;
    @Resource
    private AreaMapper areaMapper;
    @Resource
    private EnterpriseMapper enterpriseMapper;
    @Resource
    private SiteMapper siteMapper;

    /**
     * 根据区域 id 号获取该区域部署的设备 ids 集合
     * @param areaId 区域id号
     * @return List<Integer>
     */
    @Override
    public List<Integer> getDeviceIdsByAreaId(Integer areaId) {

        return deviceMapper.getDeviceIdsByAreaId(areaId);

    }

    /**
     * 根据区域 id 和企业 id 号获取该企业部署的设备 ids 集合
     * @param areaId 区域id
     * @param enterpriseId 企业id
     * @return List<Integer>
     */
    @Override
    public List<Integer> getDeviceIdsByAreaIdEnterpriseId(Integer areaId, Integer enterpriseId) {

        return deviceMapper.getDeviceIdsByAreaIdEnterpriseId(areaId, enterpriseId);

    }

    /**
     * 根据监测点id获取设备id
     * @param siteId 监测点id号
     * @return Integer
     */
    @Override
    public Integer getIdBySiteId(Integer siteId) {

        return deviceMapper.getIdBySiteId(siteId);

    }

    /**
     * 根据 id 查询设备信息
     * @param id 设备id号
     * @return Device
     */
    @Override
    public Result getOneById(Integer id) {

        //获取当前用户
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        //如果是超级管理员或者局机关理员直接返回
        if(account.getRoleId().equals(Const.SUPER_ADMIN_ID) || account.getRoleId().equals(Const.BUREAU_ADMIN_ID)){
            Device device = deviceMapper.selectById(id);
            return ResultUtils.resultWithData(ResultStatus.SUCCESS, toDeviceVo(device));
        }
        List<Integer> deviceIds;
        if(account.getRoleId().equals(Const.DISTRICT_ADMIN_ID)){
            //区级管理员
            deviceIds = this.getDeviceIdsByAreaId(account.getAreaId());
        }else if(account.getRoleId().equals(Const.ENTERPRISE_USER_ID)){
            //企业用户
            deviceIds = this.getDeviceIdsByAreaIdEnterpriseId(account.getAreaId(), account.getEnterpriseId());
        }else{
            //如果都不是未知错误
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "未知错误");
        }

        if(deviceIds.size() != 0 && !deviceIds.contains(id)){
            log.warn("尝试访问权限不足/不存在的资源, 越级查找设备");
            return ResultUtils.resultWithoutData(ResultStatus.VISITED_FORBID);
        }

        //有权. 且id正确
        Device device = deviceMapper.selectById(id);
        return ResultUtils.resultWithData(ResultStatus.SUCCESS, this.toDeviceVo(device));
    }

    /**
     * 分页获取设备列表 或者 条件查询
     * 权限处理:
     * 超级管理员可以查看所有区域的部署的设备
     * 局级管理员可以看到所有区域的部署的设备
     * 区级管理员只能看到自己所在区所部署的设备 area_id
     * 企业管理员只能看到自己所在企业所部署的设备 enterprise_id
     * 条件: 区域id, 企业id, 是否绑定监测点, 经度范围, 纬度范围
     * @param paramMap 查询条件 map
     * @param page 查询第几页
     * @param size 一页查询的记录条数
     * @return Result
     */
    @Override
    @Transactional(readOnly = true)
    public Result getDeviceVoListOrQuery(Map<String, String[]> paramMap, Integer page, Integer size) {

        paramMap.remove("page");
        paramMap.remove("size");
        //需要过滤掉不必要的参数[防止恶意篡改 url 地址中的参数]
        List<String> parms = Arrays.asList("area_id", "enterprise_id", "longitude","latitude");
        //封装查询条件
        QueryWrapper<Device> wrapper = new QueryWrapper<>();
        boolean isArea = true, isEnterprise = true;
        for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
            String k = entry.getKey();
            String[] v = entry.getValue();
            if(parms.contains(k) && !v[0].equals("")){
                //获取下标
                int index = parms.indexOf(k);
                if(index == 2){
                    String[] longitudes = v[0].split("-");
                    if(longitudes.length == 2){
                        try{
                            double v1 = Double.parseDouble(longitudes[0]);
                            double v2 = Double.parseDouble(longitudes[1]);
                            if(v1 <= v2){
                                wrapper.between("longitude", v1, v2);
                            }else{
                                return ResultUtils.resultWithoutData(ResultStatus.FAILED, "经度范围错误,低->高");
                            }
                        }catch (Exception e){
                            log.error("DeviceServiceImpl --> getDeviceVoListOrQuery: " + e.getMessage());
                            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "经度信息填写错误");
                        }
                    }else{
                        return ResultUtils.resultWithoutData(ResultStatus.FAILED, "经度信息填写错误");
                    }

                }else if(index == 3){
                    String[] latitudes = v[0].split("-");
                    if(latitudes.length == 2){
                        try{
                            double v1 = Double.parseDouble(latitudes[0]);
                            double v2 = Double.parseDouble(latitudes[1]);
                            if(v1 < v2){
                                wrapper.between("latitude", v1, v2);
                            }else{
                                return ResultUtils.resultWithoutData(ResultStatus.FAILED, "纬度范围错误,低->高");
                            }
                        }catch (Exception e){
                            log.error("DeviceServiceImpl --> getDeviceVoListOrQuery: " + e.getMessage());
                            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "纬度信息填写错误");
                        }
                    }else{
                        return ResultUtils.resultWithoutData(ResultStatus.FAILED, "纬度信息填写错误");
                    }
                }else{
                    if(k.equals("area_id")){
                        isArea = false;
                    }else if(k.equals("enterprise_id")){
                        isEnterprise = false;
                    }
                    wrapper.eq(k,v[0]);
                }
            }
        }

        //获取当前用户
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        //判断如果是区管理员或者企业用户
        if(isArea && account.getRoleId().equals(Const.DISTRICT_ADMIN_ID)){
            //区级管理员
            wrapper.eq("area_id", account.getAreaId());
        }else if(isEnterprise && account.getRoleId().equals(Const.ENTERPRISE_USER_ID)){
            //企业用户
            wrapper.eq("area_id", account.getAreaId())
                    .eq("enterprise_id", account.getEnterpriseId());
        }
        wrapper.in("is_binding", Const.NOT_BINDING, Const.BINDING);
        IPage<Device> devicePage = deviceMapper.selectPage(new Page<>(page, size), wrapper);

        List<DeviceVo> deviceVos = this.toDeviceVoList(devicePage.getRecords());
        IPage<DeviceVo> pageInfo2 = new Page<>();

        pageInfo2.setCurrent(devicePage.getCurrent());
        pageInfo2.setRecords(deviceVos);
        pageInfo2.setPages(devicePage.getPages());
        pageInfo2.setSize(devicePage.getSize());
        pageInfo2.setTotal(devicePage.getTotal());

        if(null != pageInfo2.getRecords() && !pageInfo2.getRecords().isEmpty()){
            return ResultUtils.resultWithData(ResultStatus.SUCCESS, pageInfo2);
        }else{
            return ResultUtils.resultWithoutData(ResultStatus.NOT_FOUND, "未找到任何设备信息");
        }

    }

    /**
     * 根据 id 删除设备
     * @param id 设备id号
     * @return Result
     */
    @Override
    public Result delById(Integer id) {

        //获取当前用户
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        //判断如果是区管理员或者企业用户
        List<Integer> deviceIds = null;
        if(account.getRoleId().equals(Const.DISTRICT_ADMIN_ID)){
            //区级管理员
            deviceIds = this.getDeviceIdsByAreaId(account.getAreaId());
        }else if(account.getRoleId().equals(Const.ENTERPRISE_USER_ID)){
            //企业用户
            deviceIds = this.getDeviceIdsByAreaIdEnterpriseId(account.getAreaId(), account.getEnterpriseId());
        }
        if(deviceIds != null && deviceIds.size() != 0 && !deviceIds.contains(id)){
//            log.warn("尝试删除权限不足/不存在的资源, 越级删除设备");
            return ResultUtils.resultWithoutData(ResultStatus.VISITED_FORBID, "权限不足或者不存在的资源");
        }

        //如果当前设备绑定了监测点, 是不能删除的
        if(this.deviceIsBinding(id)){
            //true为以绑定
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "当前设备已经绑定监测点,无法删除,请先解绑");
        }
        return deviceMapper.deleteById(id) == 1
                ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "成功删除该设备")
                : ResultUtils.resultWithoutData(ResultStatus.FAILED, "删除该设备信息失败");

    }

    /**
     * 新增设备
     * @param deviceVo 设备视图对象
     * @return boolean
     */
    @Override
    public Result addDevice(DeviceVo deviceVo) {

        //检查 IMEI 是否唯一
        if(deviceMapper.getIdByIMEI(deviceVo.getNbDeviceId()) == null){
            Device device = new Device();
            BeanUtil.copyProperties(deviceVo, device);
            return deviceMapper.insert(device) == 1
                    ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "新增设备信息成功")
                    : ResultUtils.resultWithoutData(ResultStatus.FAILED, "新增设备信息失败,请重试");
        }else{
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "输入的设备编号不正确,请核对正确");
        }

    }

    /**
     * 修改设备信息
     * @param deviceVo 设备视图对象
     * @return Result
     */
    @Override
    public Result modifyDevice(DeviceVo deviceVo) {
        //获取当前用户
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        //判断如果是区管理员或者企业用户
        List<Integer> deviceIds = null;
        if(account.getRoleId().equals(Const.DISTRICT_ADMIN_ID)){
            //区级管理员
            deviceIds = this.getDeviceIdsByAreaId(account.getAreaId());
        }else if(account.getRoleId().equals(Const.ENTERPRISE_USER_ID)){
            //企业用户
            deviceIds = this.getDeviceIdsByAreaId(account.getEnterpriseId());
        }
        if(deviceIds != null && deviceIds.size() != 0 && !deviceIds.contains(deviceVo.getId())){
//            log.warn("尝试访问权限不足/不存在的资源, 越级查找设备");
            return ResultUtils.resultWithoutData(ResultStatus.VISITED_FORBID, "权限不足或者不存在的资源");
        }

        Device device = deviceMapper.selectById(deviceVo.getId());
        //判断设备是否绑定
        if(deviceIsBinding(deviceVo.getId())){//绑定了
            //获取该设备信息
            if(!device.getAreaId().equals(deviceVo.getAreaId()) || !device.getEnterpriseId().equals(deviceVo.getEnterpriseId())){
                //修改了区域或者企业
                return ResultUtils.resultWithoutData(ResultStatus.FAILED, "修改失败, 该设备已绑定监测点, 请先解绑");
            }
        }

        BeanUtil.copyProperties(deviceVo, device);

        return deviceMapper.updateById(device) == 1
                ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "更新设备信息成功")
                : ResultUtils.resultWithoutData(ResultStatus.FAILED, "更新该设备信息失败, 请重试");
    }

    /**
     * 查询未绑定监测点的设备信息
     * @param page 第几页
     * @param size 一页几条数据
     * @return IPage<DeviceVo>
     */
    @Override
    @Transactional(readOnly = true)
    public IPage<DeviceVo> getNoBindingList(Integer page, Integer size) {

        IPage<Device> isBinding = deviceMapper.selectPage(new Page<>(page, size), new QueryWrapper<Device>().eq("is_binding", Const.BINDING));
        List<DeviceVo> deviceVos = this.toDeviceVoList(isBinding.getRecords());
        IPage<DeviceVo> pageInfo2 = new Page<>();

        pageInfo2.setCurrent(isBinding.getCurrent());
        pageInfo2.setRecords(deviceVos);
        pageInfo2.setPages(isBinding.getPages());
        pageInfo2.setSize(isBinding.getSize());
        pageInfo2.setTotal(isBinding.getTotal());

        return pageInfo2;
    }

    /**
     * 判断设备是否绑定
     * @param id 设备id
     * @return boolean
     */
    @Override
    public boolean deviceIsBinding(Integer id) {

        int flg = deviceMapper.deviceIsBinding(id);
        return Const.BINDING.equals(flg);

    }

    /**
     * 通过设备id获取监测点id
     * @param id 设备id
     * @return int
     */
    @Override
    public int getSiteIdById(Integer id) {

        return deviceMapper.getSiteIdById(id);

    }

    /**
     * 根据IMEI更新设备经纬度
     * @param IMEI 设备标识
     * @param LngAndLat 经纬度
     * @return boolean
     */
    @Override
    public boolean updateLngLatByIMEI(String IMEI, double[] LngAndLat) {
        Device device = deviceMapper.selectOne(new QueryWrapper<Device>().eq("nb_device_id", IMEI));
        if(null != device){
            device.setLongitude(LngAndLat[0]);//经度
            device.setLatitude(LngAndLat[1]);//纬度
            deviceMapper.updateById(device);
            return true;
        }
        return false;
    }

    /**
     * 设备绑定监测点接口
     * @param deviceSiteVo 设备视图对象
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deviceBindingOr(DeviceSiteVo deviceSiteVo) {

        //解绑需要把设备的监测点id号置为 NOT_BINDING
        int val = deviceSiteVo.getIsBinding().equals(Const.BINDING) ? Const.BINDING : Const.NOT_BINDING;
        Device device = Device.builder().id(deviceSiteVo.getDeviceId()).deviceSiteId(val == Const.BINDING ? deviceSiteVo.getSiteId() : Const.NOT_BINDING).isBinding(val).build();
        int b = deviceMapper.updateById(device);
        Site site = Site.builder().id(deviceSiteVo.getSiteId()).isBinding(val).build();
        int s = siteMapper.updateById(site);
        return (b + s) == 2;

    }

    /**
     * 根据区域id和企业id查找设备列表信息
     * @param areaId 区域id
     * @param enterpriseId 企业id
     * @return List<Device>
     */
    @Override
    public List<Device> getDeviceByAreaIdAndId(Integer areaId, Integer enterpriseId) {

        return deviceMapper.selectList(new QueryWrapper<Device>().eq("area_id", areaId)
                .eq("enterprise_id", enterpriseId)
                .eq("is_binding", Const.BINDING)
        );

    }

    /**
     * 分页获取待处理设备信息(设备注册)
     * @param page 第几页
     * @param size 一页几条数据
     * @param flg 标志
     * @return IPage<RegDeviceVo>
     */
    @Override
    public IPage<RegDeviceVo> getRegDeviceVoList(Integer page, Integer size, Integer flg) {

        IPage<Device> iPage = deviceMapper.selectPage(new Page<>(page, size), new QueryWrapper<Device>().eq("is_binding", flg));
        IPage<RegDeviceVo> pageInfo = new Page<>();

        pageInfo.setRecords(toRegDeviceVoList(iPage.getRecords()));
        pageInfo.setCurrent(iPage.getCurrent());
        pageInfo.setPages(iPage.getPages());
        pageInfo.setSize(iPage.getSize());
        pageInfo.setTotal(iPage.getTotal());

        return pageInfo;

    }

    /**
     * 完善设备注册信息
     * @param deviceVo 设备视图对象
     * @return Result
     */
    @Override
    public Result doWait(DeviceVo deviceVo) {

        //检查设备编号是否唯一
        if(deviceMapper.getIdByIMEI(deviceVo.getNbDeviceId()) == null){
            return deviceMapper.updateById(
                    Device.builder()
                            .id(deviceVo.getId())
                            .nbDeviceId(deviceVo.getNbDeviceId())
                            .createUserid(deviceVo.getCreateUserid())
                            .areaId(deviceVo.getAreaId())
                            .enterpriseId(deviceVo.getEnterpriseId())
                            .deviceSiteId(0)
                            .updateUserid(deviceVo.getUpdateUserid())
                            .productEnterprise(deviceVo.getProductEnterprise())
                            .productDate(deviceVo.getProductDate())
                            .lastYearcheck(deviceVo.getLastYearcheck())
                            .lastAdjusting(deviceVo.getLastAdjusting())
                            .longitude(deviceVo.getLongitude())
                            .latitude(deviceVo.getLatitude())
                            .isBinding(Const.NOT_BINDING)
                            .build()
            ) == 1
                    ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "设备注册信息登记完成")
                    : ResultUtils.resultWithoutData(ResultStatus.FAILED, "设备注册信息登记失败, 请重试");
        }else{
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "该设备编号已被注册过, 请核对正确");
        }

    }

    /**
     * 将注册信息基本对象保存至数据库
     * @param regDeviceVo 注册设备基本信息对象
     * @return Result
     */
    @Override
    public Result saveRegDevice(RegDeviceVo regDeviceVo) {

        //检查该设备是否已被注册过
        if(deviceMapper.getIdByIMEI(regDeviceVo.getIMEI()) == null){
            return deviceMapper.insert(
                    Device.builder()
                            .nbDeviceId(regDeviceVo.getIMEI())
                            .createDatetime(regDeviceVo.getRegDateTime())
                            .updateDatetime(LocalDateTime.now())
                            .longitude(regDeviceVo.getLongitude())
                            .latitude(regDeviceVo.getLatitude())
                            .isBinding(Const.NEW_DEVICE)
                            .build()
            ) == 1
                    ? ResultUtils.resultWithoutData(ResultStatus.SUCCESS, "保存注册设备信息成功")
                    : ResultUtils.resultWithoutData(ResultStatus.FAILED, "保存注册设备信息失败,请重试");
        }else{
            log.error("DeviceServiceImpl --> saveRegDevice: 保存注册设备信息失败, 已存在该设备信息");
            return ResultUtils.resultWithoutData(ResultStatus.FAILED, "保存注册设备信息失败, 已存在该设备信息");
        }

    }

    /**
     * 根据 区域id和企业id查询该企业下的设备个数
     * @param areaId 区域id
     * @param enterpriseId 企业id
     * @return int
     */
    @Override
    public int checkDeviceCountByAreaIdAndEnterpriseId(Integer areaId, Integer enterpriseId) {

        return deviceMapper.checkDeviceCountByAreaIdAndEnterpriseId(areaId, enterpriseId);

    }

    /**
     * 根据当前登录的用户获取该用户所拥有的设备id的权限，默认返回第一个
     * @return Integer 第一个设备的id号
     */
    @Override
    public Integer getDefaultDeviceId() {

        //1、如果是超级管理员或者局级管理员，直接返回设备列表的第一个数据
        //获取当前用户
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        List<Device> devices = null;
        QueryWrapper<Device> wrapper = new QueryWrapper<>();
        if(account.getRoleId().equals(Const.SUPER_ADMIN_ID) || account.getRoleId().equals(Const.BUREAU_ADMIN_ID)){
            //超级管理员或者局级管理员
            wrapper.eq("is_binding", Const.BINDING);
            devices = deviceMapper.selectList(wrapper);
        }
        //2、如果是区级管理员，查询条件增加区域id
        else if(account.getRoleId().equals(Const.DISTRICT_ADMIN_ID)){

            wrapper.eq("area_id", account.getAreaId());
            wrapper.eq("is_binding", Const.BINDING);
            devices = deviceMapper.selectList(wrapper);
        }
        //3、如果是企业用户，查询条件增加区域和企业id号
        else if(account.getRoleId().equals(Const.ENTERPRISE_USER_ID)){
            wrapper.eq("area_id", account.getAreaId());
            wrapper.eq("enterprise_id", account.getEnterpriseId());
            wrapper.eq("is_binding", Const.BINDING);
            devices = deviceMapper.selectList(wrapper);
        }
        if(devices != null && !devices.isEmpty()){
            return devices.get(0).getId();
        }
        return null;

    }

    /**
     * 将 List<Device> 转换成 List<DeviceVo>
     * @param devices 设备列表
     * @return List<DeviceVo>
     */
    private List<DeviceVo> toDeviceVoList(List<Device> devices){

        //声明变量
        List<DeviceVo> deviceVoList = new ArrayList<>(devices.size());
        //遍历设备列表
        devices.forEach(device -> deviceVoList.add(toDeviceVo(device)));
        return deviceVoList;

    }


    /**
     * 将单个device对象转换换成DeviceVo对象
     * @param device Device
     * @return DeviceVo
     */
    public DeviceVo toDeviceVo(Device device){

        //1. 首先把相同的字段填充
        DeviceVo deviceVo = new DeviceVo();
        BeanUtil.copyProperties(device, deviceVo);
        //2. 填充其他字段: createName, areaName, enterpriseName, updateName, detailAddress
        if(deviceVo.getDescription() != null && deviceVo.getDescription().isEmpty()){
            deviceVo.setDescription("未设置");
        }
        deviceVo.setCreateName(accountMapper.getAccNameById(device.getCreateUserid()));
        deviceVo.setAreaName(areaMapper.getAreaNameById(device.getAreaId()));
        deviceVo.setEnterpriseName(enterpriseMapper.getEnterNameById(device.getAreaId(), device.getEnterpriseId()));
        deviceVo.setUpdateName(accountMapper.getAccNameById(device.getUpdateUserid()));
        deviceVo.setSiteDetailAddress(siteMapper.getSiteDetailNameById(deviceVo.getDeviceSiteId()));
        deviceVo.setDetailAddress(LocationUtils.getAddressDetails(
                Location.builder()
                        .lng(device.getLongitude())
                        .lat(device.getLatitude())
                        .build()).getFormatted_address()
        );
        return deviceVo;

    }

    /**
     * 将 List<Device> 转换成 List<RegDeviceVo>
     * @param devices 设备列表
     * @return List<RegDeviceVo>
     */
    private List<RegDeviceVo> toRegDeviceVoList(List<Device> devices){

        //声明变量
        List<RegDeviceVo> regDeviceVoList = new ArrayList<>(devices.size());
        //遍历设备列表
        devices.forEach(device -> regDeviceVoList.add(toRegDeviceVo(device)));
        return regDeviceVoList;

    }

    /**
     * 将 Device 转换成
     * @param device RegDeviceVo
     * @return RegDeviceVo
     */
    private RegDeviceVo toRegDeviceVo(Device device){

        return RegDeviceVo.builder()
                .id(device.getId())
                .IMEI(device.getNbDeviceId())
                .regDateTime(device.getCreateDatetime())
                .longitude(device.getLongitude())
                .latitude(device.getLatitude())
                .build();

    }


}
